//! 资源管理器
//! 
//! 负责系统资源的统一管理，包括：
//! - 内存管理
//! - 连接池管理
//! - 线程池管理
//! - 监控指标收集

use std::collections::HashMap;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use tokio::sync::RwLock;

use crate::error::{KernelError, Result};

/// 资源类型
#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
pub enum ResourceType {
    /// 内存资源
    Memory,
    /// 连接池资源
    ConnectionPool,
    /// 线程池资源
    ThreadPool,
    /// 文件句柄资源
    FileHandle,
    /// 网络连接资源
    NetworkConnection,
    /// 自定义资源
    Custom(String),
}

/// 资源配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceConfig {
    /// 最大限制
    pub max_limit: Option<usize>,
    /// 最小保留
    pub min_reserved: Option<usize>,
    /// 超时时间（毫秒）
    pub timeout_ms: Option<u64>,
    /// 清理间隔（毫秒）
    pub cleanup_interval_ms: Option<u64>,
    /// 自定义配置
    pub custom_config: HashMap<String, serde_json::Value>,
}

/// 资源使用统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceUsage {
    /// 资源类型
    pub resource_type: ResourceType,
    /// 当前使用量
    pub current_usage: usize,
    /// 最大使用量
    pub max_usage: usize,
    /// 总分配量
    pub total_allocated: usize,
    /// 使用率（百分比）
    pub usage_percentage: f64,
    /// 最后更新时间
    pub last_updated: chrono::DateTime<chrono::Utc>,
}

/// 资源管理器
pub struct ResourceManager {
    /// 资源配置
    configs: Arc<RwLock<HashMap<ResourceType, ResourceConfig>>>,
    /// 资源使用统计
    usage_stats: Arc<RwLock<HashMap<ResourceType, ResourceUsage>>>,
    /// 资源监控器
    monitors: Arc<RwLock<Vec<Arc<dyn ResourceMonitor>>>>,
}

/// 资源监控器接口
#[async_trait::async_trait]
pub trait ResourceMonitor: Send + Sync {
    /// 监控器ID
    fn id(&self) -> &str;
    
    /// 监控的资源类型
    fn monitored_resources(&self) -> Vec<ResourceType>;
    
    /// 收集资源使用情况
    async fn collect_usage(&self, resource_type: &ResourceType) -> Result<ResourceUsage>;
    
    /// 资源告警检查
    async fn check_alerts(&self, usage: &ResourceUsage) -> Result<Vec<ResourceAlert>>;
}

/// 资源告警
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceAlert {
    /// 告警级别
    pub level: AlertLevel,
    /// 资源类型
    pub resource_type: ResourceType,
    /// 告警消息
    pub message: String,
    /// 当前使用量
    pub current_usage: usize,
    /// 阈值
    pub threshold: usize,
    /// 告警时间
    pub timestamp: chrono::DateTime<chrono::Utc>,
}

/// 告警级别
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AlertLevel {
    Info,
    Warning,
    Critical,
    Emergency,
}

impl ResourceManager {
    /// 创建新的资源管理器
    pub fn new() -> Self {
        Self {
            configs: Arc::new(RwLock::new(HashMap::new())),
            usage_stats: Arc::new(RwLock::new(HashMap::new())),
            monitors: Arc::new(RwLock::new(Vec::new())),
        }
    }
    
    /// 初始化资源管理器
    pub async fn initialize(&self) -> Result<()> {
        tracing::info!("初始化资源管理器");
        
        // 设置默认配置
        self.set_default_configs().await?;
        
        // 启动监控任务
        self.start_monitoring().await?;
        
        tracing::info!("资源管理器初始化完成");
        Ok(())
    }
    
    /// 设置资源配置
    pub async fn set_resource_config(
        &self,
        resource_type: ResourceType,
        config: ResourceConfig,
    ) -> Result<()> {
        let mut configs = self.configs.write().await;
        configs.insert(resource_type.clone(), config);
        
        tracing::debug!("资源配置已更新: {:?}", resource_type);
        Ok(())
    }
    
    /// 获取资源配置
    pub async fn get_resource_config(&self, resource_type: &ResourceType) -> Option<ResourceConfig> {
        let configs = self.configs.read().await;
        configs.get(resource_type).cloned()
    }
    
    /// 注册资源监控器
    pub async fn register_monitor(&self, monitor: Arc<dyn ResourceMonitor>) -> Result<()> {
        let mut monitors = self.monitors.write().await;
        monitors.push(monitor);
        Ok(())
    }
    
    /// 获取资源使用统计
    pub async fn get_resource_usage(&self, resource_type: &ResourceType) -> Option<ResourceUsage> {
        let usage_stats = self.usage_stats.read().await;
        usage_stats.get(resource_type).cloned()
    }
    
    /// 获取所有资源使用统计
    pub async fn get_all_resource_usage(&self) -> HashMap<ResourceType, ResourceUsage> {
        let usage_stats = self.usage_stats.read().await;
        usage_stats.clone()
    }
    
    /// 更新资源使用统计
    pub async fn update_resource_usage(
        &self,
        resource_type: ResourceType,
        usage: ResourceUsage,
    ) -> Result<()> {
        let mut usage_stats = self.usage_stats.write().await;
        usage_stats.insert(resource_type, usage);
        Ok(())
    }
    
    /// 检查资源限制
    pub async fn check_resource_limit(
        &self,
        resource_type: &ResourceType,
        requested: usize,
    ) -> Result<bool> {
        let configs = self.configs.read().await;
        let usage_stats = self.usage_stats.read().await;
        
        if let Some(config) = configs.get(resource_type) {
            if let Some(max_limit) = config.max_limit {
                if let Some(current_usage) = usage_stats.get(resource_type) {
                    return Ok(current_usage.current_usage + requested <= max_limit);
                }
            }
        }
        
        // 如果没有配置限制，默认允许
        Ok(true)
    }
    
    /// 申请资源
    pub async fn allocate_resource(
        &self,
        resource_type: ResourceType,
        amount: usize,
    ) -> Result<ResourceAllocation> {
        // 检查资源限制
        if !self.check_resource_limit(&resource_type, amount).await? {
            return Err(KernelError::resource(format!(
                "资源申请超出限制: {:?}, 请求量: {}",
                resource_type, amount
            )));
        }
        
        // 更新使用统计
        let mut usage_stats = self.usage_stats.write().await;
        let usage = usage_stats.entry(resource_type.clone()).or_insert_with(|| {
            ResourceUsage {
                resource_type: resource_type.clone(),
                current_usage: 0,
                max_usage: 0,
                total_allocated: 0,
                usage_percentage: 0.0,
                last_updated: chrono::Utc::now(),
            }
        });
        
        usage.current_usage += amount;
        usage.total_allocated += amount;
        usage.max_usage = usage.max_usage.max(usage.current_usage);
        usage.last_updated = chrono::Utc::now();
        
        // 计算使用率
        if let Some(config) = self.configs.read().await.get(&resource_type) {
            if let Some(max_limit) = config.max_limit {
                usage.usage_percentage = (usage.current_usage as f64 / max_limit as f64) * 100.0;
            }
        }
        
        Ok(ResourceAllocation {
            resource_type,
            amount,
            allocation_id: uuid::Uuid::new_v4().to_string(),
            allocated_at: chrono::Utc::now(),
        })
    }
    
    /// 释放资源
    pub async fn deallocate_resource(&self, allocation: ResourceAllocation) -> Result<()> {
        let mut usage_stats = self.usage_stats.write().await;
        
        if let Some(usage) = usage_stats.get_mut(&allocation.resource_type) {
            usage.current_usage = usage.current_usage.saturating_sub(allocation.amount);
            usage.last_updated = chrono::Utc::now();
            
            // 重新计算使用率
            if let Some(config) = self.configs.read().await.get(&allocation.resource_type) {
                if let Some(max_limit) = config.max_limit {
                    usage.usage_percentage = (usage.current_usage as f64 / max_limit as f64) * 100.0;
                }
            }
        }
        
        Ok(())
    }
    
    /// 设置默认配置
    async fn set_default_configs(&self) -> Result<()> {
        let default_configs = vec![
            (ResourceType::Memory, ResourceConfig {
                max_limit: Some(1024 * 1024 * 1024), // 1GB
                min_reserved: Some(128 * 1024 * 1024), // 128MB
                timeout_ms: None,
                cleanup_interval_ms: Some(60000), // 1分钟
                custom_config: HashMap::new(),
            }),
            (ResourceType::ConnectionPool, ResourceConfig {
                max_limit: Some(100),
                min_reserved: Some(10),
                timeout_ms: Some(30000), // 30秒
                cleanup_interval_ms: Some(300000), // 5分钟
                custom_config: HashMap::new(),
            }),
            (ResourceType::ThreadPool, ResourceConfig {
                max_limit: Some(200),
                min_reserved: Some(10),
                timeout_ms: None,
                cleanup_interval_ms: None,
                custom_config: HashMap::new(),
            }),
        ];
        
        let mut configs = self.configs.write().await;
        for (resource_type, config) in default_configs {
            configs.insert(resource_type, config);
        }
        
        Ok(())
    }
    
    /// 启动监控任务
    async fn start_monitoring(&self) -> Result<()> {
        let monitors = self.monitors.clone();
        let usage_stats = self.usage_stats.clone();
        
        tokio::spawn(async move {
            let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(30));
            
            loop {
                interval.tick().await;
                
                let monitors_guard = monitors.read().await;
                for monitor in monitors_guard.iter() {
                    for resource_type in monitor.monitored_resources() {
                        if let Ok(usage) = monitor.collect_usage(&resource_type).await {
                            let mut stats = usage_stats.write().await;
                            stats.insert(resource_type.clone(), usage.clone());
                            
                            // 检查告警
                            if let Ok(alerts) = monitor.check_alerts(&usage).await {
                                for alert in alerts {
                                    tracing::warn!("资源告警: {:?}", alert);
                                }
                            }
                        }
                    }
                }
            }
        });
        
        Ok(())
    }
}

/// 资源分配记录
#[derive(Debug, Clone)]
pub struct ResourceAllocation {
    pub resource_type: ResourceType,
    pub amount: usize,
    pub allocation_id: String,
    pub allocated_at: chrono::DateTime<chrono::Utc>,
}

impl Default for ResourceConfig {
    fn default() -> Self {
        Self {
            max_limit: None,
            min_reserved: None,
            timeout_ms: None,
            cleanup_interval_ms: None,
            custom_config: HashMap::new(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_resource_manager() {
        let resource_manager = ResourceManager::new();
        resource_manager.initialize().await.unwrap();
        
        // 测试资源分配
        let allocation = resource_manager
            .allocate_resource(ResourceType::Memory, 1024)
            .await
            .unwrap();
        
        assert_eq!(allocation.amount, 1024);
        assert_eq!(allocation.resource_type, ResourceType::Memory);
        
        // 检查使用统计
        let usage = resource_manager
            .get_resource_usage(&ResourceType::Memory)
            .await
            .unwrap();
        
        assert_eq!(usage.current_usage, 1024);
        
        // 释放资源
        resource_manager.deallocate_resource(allocation).await.unwrap();
        
        // 检查使用统计
        let usage = resource_manager
            .get_resource_usage(&ResourceType::Memory)
            .await
            .unwrap();
        
        assert_eq!(usage.current_usage, 0);
    }
    
    #[tokio::test]
    async fn test_resource_limit() {
        let resource_manager = ResourceManager::new();
        resource_manager.initialize().await.unwrap();
        
        // 设置较小的内存限制
        let config = ResourceConfig {
            max_limit: Some(1024),
            ..Default::default()
        };
        
        resource_manager
            .set_resource_config(ResourceType::Memory, config)
            .await
            .unwrap();
        
        // 申请资源
        let allocation = resource_manager
            .allocate_resource(ResourceType::Memory, 512)
            .await
            .unwrap();
        
        // 尝试申请超出限制的资源
        let result = resource_manager
            .allocate_resource(ResourceType::Memory, 1024)
            .await;
        
        assert!(result.is_err());
        
        // 释放资源
        resource_manager.deallocate_resource(allocation).await.unwrap();
    }
}
